﻿using System;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.Decompiler.ILAst;
using Mono.Cecil;

namespace CSLua
{
	// Token: 0x02000028 RID: 40
	public abstract class CodeWriter
	{
		// Token: 0x06000190 RID: 400 RVA: 0x0000A6E7 File Offset: 0x000088E7
		public CodeWriter(TypeDefinition type)
		{
			this.type = type;
		}

		// Token: 0x06000191 RID: 401 RVA: 0x0000A717 File Offset: 0x00008917
		public CodeWriter stringLite(string str)
		{
			this.code(str.luaLite());
			return this;
		}

		// Token: 0x06000192 RID: 402 RVA: 0x0000A727 File Offset: 0x00008927
		private bool isIdChar(char c)
		{
			return c == '_' || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
		}

		// Token: 0x06000193 RID: 403 RVA: 0x0000A754 File Offset: 0x00008954
		private void checkToken(string nextToken)
		{
			if (this.codebuilder.Length > 0 && nextToken.Length > 0)
			{
				char last = this.codebuilder[this.codebuilder.Length - 1];
				char cbegin = nextToken[0];
				if (this.isIdChar(last) && this.isIdChar(cbegin))
				{
					this.codebuilder.Append(" ");
				}
			}
		}

		// Token: 0x06000194 RID: 404 RVA: 0x0000A7BC File Offset: 0x000089BC
		public CodeWriter code(string code)
		{
			this.checkToken(code);
			this.codebuilder.Append(code);
			return this;
		}

		// Token: 0x1700003B RID: 59
		// (get) Token: 0x06000195 RID: 405
		public abstract ITokens tokens { get; }

		// Token: 0x06000196 RID: 406 RVA: 0x0000A7D4 File Offset: 0x000089D4
		public CodeWriter splitList<T>(IEnumerable<T> ie, string spliter, CodeWriter.DotItem<T> item)
		{
			int index = 0;
			int strLen = this.codebuilder.Length;
			foreach (T i in ie)
			{
				if (this.codebuilder.Length > strLen)
				{
					this.code(spliter);
				}
				item(i, index++);
			}
			return this;
		}

		// Token: 0x06000197 RID: 407 RVA: 0x0000A848 File Offset: 0x00008A48
		public CodeWriter get(string left, string field)
		{
			return this.code(left + "." + field);
		}

		// Token: 0x06000198 RID: 408 RVA: 0x0000A85C File Offset: 0x00008A5C
		public CodeWriter assignLocal(string left, string val)
		{
			return this.code(left + " = " + val);
		}

		// Token: 0x06000199 RID: 409 RVA: 0x0000A870 File Offset: 0x00008A70
		public CodeWriter defineLocalValue(string valueName, string initValue = null)
		{
			this.writeLocalValueDefine(valueName, initValue);
			return this.nextLine();
		}

		// Token: 0x0600019A RID: 410
		protected abstract void writeLocalValueDefine(string valueName, string initValue);

		// Token: 0x0600019B RID: 411
		public abstract CodeWriter beginLambda();

		// Token: 0x0600019C RID: 412
		public abstract CodeWriter endLambda();

		// Token: 0x0600019D RID: 413 RVA: 0x0000A880 File Offset: 0x00008A80
		public CodeWriter dot<T>(IEnumerable<T> ie, CodeWriter.DotItem<T> item)
		{
			return this.splitList<T>(ie, " , ", item);
		}

		// Token: 0x0600019E RID: 414 RVA: 0x0000A88F File Offset: 0x00008A8F
		public CodeWriter codeFormat(string code, params object[] args)
		{
			return this.code(string.Format(code, args));
		}

		// Token: 0x0600019F RID: 415 RVA: 0x0000A89E File Offset: 0x00008A9E
		public CodeWriter nextLine()
		{
			return this.nextLine(0);
		}

		// Token: 0x060001A0 RID: 416 RVA: 0x0000A8A7 File Offset: 0x00008AA7
		public CodeWriter push()
		{
			this.stack.Push(this.codebuilder);
			this.codebuilder = new StringBuilder();
			return this;
		}

		// Token: 0x060001A1 RID: 417 RVA: 0x0000A8C6 File Offset: 0x00008AC6
		public StringBuilder popBuilder()
		{
			StringBuilder result = this.codebuilder;
			this.codebuilder = this.stack.Pop();
			return result;
		}

		// Token: 0x060001A2 RID: 418 RVA: 0x0000A8DF File Offset: 0x00008ADF
		public string pop()
		{
			object obj = this.codebuilder;
			this.codebuilder = this.stack.Pop();
			return obj.ToString();
		}

		// Token: 0x060001A3 RID: 419
		public abstract CodeWriter luaNil();

		// Token: 0x060001A4 RID: 420 RVA: 0x0000A8FD File Offset: 0x00008AFD
		public CodeWriter luaBoolean(bool value)
		{
			this.code(value ? "true" : "false");
			return this;
		}

		// Token: 0x060001A5 RID: 421 RVA: 0x0000A916 File Offset: 0x00008B16
		public CodeWriter luaNumber(long val)
		{
			this.code(val.ToString());
			return this;
		}

		// Token: 0x060001A6 RID: 422 RVA: 0x0000A928 File Offset: 0x00008B28
		public CodeWriter luaNumber(float fval)
		{
			if (float.IsNaN(fval))
			{
				this.code("(0.0/0.0)");
			}
			else if (float.IsNegativeInfinity(fval))
			{
				this.code("(-1.0/0.0)");
			}
			else if (float.IsPositiveInfinity(fval))
			{
				this.code("(1.0/0.0)");
			}
			else
			{
				this.code(fval.ToString());
			}
			return this;
		}

		// Token: 0x060001A7 RID: 423 RVA: 0x0000A988 File Offset: 0x00008B88
		public CodeWriter luaNumber(double fval)
		{
			if (double.IsNaN(fval))
			{
				this.code("(0.0/0.0)");
			}
			else if (double.IsNegativeInfinity(fval))
			{
				this.code("(-1.0/0.0)");
			}
			else if (double.IsPositiveInfinity(fval))
			{
				this.code("(1.0/0.0)");
			}
			else
			{
				this.code(fval.ToString());
			}
			return this;
		}

		// Token: 0x060001A8 RID: 424 RVA: 0x0000A9E6 File Offset: 0x00008BE6
		public CodeWriter callFunc(string func)
		{
			return this.callFunc<char>(func, "", delegate(char x, int y)
			{
			});
		}

		// Token: 0x060001A9 RID: 425 RVA: 0x0000AA13 File Offset: 0x00008C13
		public CodeWriter callFunc(string func, string first)
		{
			return this.callFunc<char>(func, first, "", delegate(char x, int y)
			{
			});
		}

		// Token: 0x060001AA RID: 426 RVA: 0x0000AA44 File Offset: 0x00008C44
		public CodeWriter callFunc<T>(string func, string first, IEnumerable<T> ie, CodeWriter.DotItem<T> item)
		{
			this.code(func + "(" + first);
			this.dot<T>(ie, delegate(T e, int i)
			{
				if (i == 0)
				{
					this.code(",");
				}
				item(e, i);
			});
			this.code(")");
			return this;
		}

		// Token: 0x060001AB RID: 427 RVA: 0x0000AA9A File Offset: 0x00008C9A
		public CodeWriter callFunc<T>(string func, IEnumerable<T> ie, CodeWriter.DotItem<T> item)
		{
			this.code(func).code("(");
			this.dot<T>(ie, item);
			this.code(")");
			return this;
		}

		// Token: 0x060001AC RID: 428 RVA: 0x0000AAC4 File Offset: 0x00008CC4
		internal void code(object cSLValueCopy)
		{
			throw new NotImplementedException();
		}

		// Token: 0x060001AD RID: 429 RVA: 0x0000AACB File Offset: 0x00008CCB
		public CodeWriter callVirtualFunc(string self, string func)
		{
			return this.callVirtualFunc<char>(self, func, "", delegate(char x, int y)
			{
			});
		}

		// Token: 0x060001AE RID: 430
		public abstract CodeWriter callVirtualFunc<T>(string self, string func, IEnumerable<T> ie, CodeWriter.DotItem<T> item);

		// Token: 0x060001AF RID: 431 RVA: 0x0000AAF9 File Offset: 0x00008CF9
		public CodeWriter shiftRightNewLine()
		{
			return this.nextLine(1);
		}

		// Token: 0x060001B0 RID: 432 RVA: 0x0000AB04 File Offset: 0x00008D04
		public CodeWriter shiftLeftNewLine(string token)
		{
			if (this.codebuilder[this.codebuilder.Length - 1] == '\t')
			{
				this.codebuilder.Remove(this.codebuilder.Length - 1, 1);
			}
			this.tab--;
			if (token != null)
			{
				this.code(token);
			}
			this.nextLine(0);
			return this;
		}

		// Token: 0x060001B1 RID: 433 RVA: 0x0000AB6C File Offset: 0x00008D6C
		public CodeWriter shiftLeftNewLine(Action token)
		{
			if (this.codebuilder[this.codebuilder.Length - 1] == '\t')
			{
				this.codebuilder.Remove(this.codebuilder.Length - 1, 1);
			}
			this.tab--;
			if (token != null)
			{
				token();
			}
			this.nextLine(0);
			return this;
		}

		// Token: 0x060001B2 RID: 434 RVA: 0x0000ABD0 File Offset: 0x00008DD0
		public CodeWriter shiftLeft(string token)
		{
			if (this.codebuilder[this.codebuilder.Length - 1] == '\t')
			{
				this.codebuilder.Remove(this.codebuilder.Length - 1, 1);
			}
			this.tab--;
			if (token != null)
			{
				this.code(token);
			}
			return this;
		}

		// Token: 0x060001B3 RID: 435
		public abstract CodeWriter commentLine(string common);

		// Token: 0x060001B4 RID: 436
		public abstract CodeWriter comment(string common);

		// Token: 0x060001B5 RID: 437 RVA: 0x0000AC30 File Offset: 0x00008E30
		private CodeWriter nextLine(int tabOffset)
		{
			this.codebuilder.Append("\r\n");
			this.tab = Math.Max(0, this.tab + tabOffset);
			for (int i = 0; i < this.tab; i++)
			{
				this.codebuilder.Append("\t");
			}
			return this;
		}

		// Token: 0x060001B6 RID: 438
		public abstract CodeWriter beginDefineMethod(string typeName, bool isStatic, string methodName, Action param = null);

		// Token: 0x060001B7 RID: 439
		public abstract CodeWriter endDefineMethod();

		// Token: 0x060001B8 RID: 440 RVA: 0x0000AC85 File Offset: 0x00008E85
		public string src()
		{
			return this.codebuilder.ToString();
		}

		// Token: 0x060001B9 RID: 441 RVA: 0x0000AC92 File Offset: 0x00008E92
		public string errors()
		{
			return this.errorBuilder.ToString();
		}

		// Token: 0x060001BA RID: 442
		public abstract void reportExpressionError(MethodBodyPhase methodBuilder, ILNode expressionContext, ILNode expression, string msg);

		// Token: 0x060001BB RID: 443
		public abstract void reportExpressionNotsupport(MethodBodyPhase methodBuilder, ILNode expressionContext, ILNode expression);

		// Token: 0x0400009C RID: 156
		public readonly TypeDefinition type;

		// Token: 0x0400009D RID: 157
		private Stack<StringBuilder> stack = new Stack<StringBuilder>();

		// Token: 0x0400009E RID: 158
		private StringBuilder codebuilder = new StringBuilder();

		// Token: 0x0400009F RID: 159
		protected StringBuilder errorBuilder = new StringBuilder();

		// Token: 0x040000A0 RID: 160
		private int tab;

		// Token: 0x040000A1 RID: 161
		private static char[] key_str = new char[]
		{
			'\'',
			'\n'
		};

		// Token: 0x02000036 RID: 54
		// (Invoke) Token: 0x060001DD RID: 477
		public delegate void DotItem<T>(T i, int index);
	}
}
